package com.atguigu.guli.service.ucenter.service.impl;

import com.atguigu.guli.common.util.utils.HttpClientUtils;
import com.atguigu.guli.service.base.consts.Keys;
import com.atguigu.guli.service.base.handler.JwtHelper;
import com.atguigu.guli.service.base.handler.JwtInfo;
import com.atguigu.guli.service.ucenter.entity.Member;
import com.atguigu.guli.service.ucenter.mapper.MemberMapper;
import com.atguigu.guli.service.ucenter.properties.WxLoginProperties;
import com.atguigu.guli.service.ucenter.service.WxService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.Gson;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpSession;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Map;
import java.util.UUID;
@Service
public class WxServiceImpl implements WxService {
    @Autowired
    WxLoginProperties wxLoginProperties;
    @Autowired
    MemberMapper memberMapper;
    @Override
    public String wxLogin(HttpSession session) {
        //访问时，让浏览器重定向访问二维码接口地址获取二维码
        String url = "https://open.weixin.qq.com/connect/qrconnect" +
                "?appid=%s" +  //在wx端注册的应用id
                "&redirect_uri=%s" + // 用户授权登录后wx让浏览器回调的接口地址
                "&response_type=code" +
                "&scope=snsapi_login" +
                "&state=%s" +
                "#wechat_redirect";
        String redirecturi = null;
        try {
            //http://localhost:8160/api/ucenter/wx/callback?code=031MSbGa1G04aB0jA6Ja1eG0eJ2MSbGJ&state=cfedc3892efd4aecb100233fa29f2e57
            //用户扫码确认授权后的回调地址 域名必须和 appid在wx中注册时的授权回调域的域名一样
            //如果不一样，wx回调会失败，它会检查是否匹配

            redirecturi = URLEncoder.encode(wxLoginProperties.getRedirectUri(),"UTF-8");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        String state = UUID.randomUUID().toString().replace("-" , "");
        session.setAttribute(Keys.WX_STATE_KEY , state);
        url = String.format(url , wxLoginProperties.getAppid() ,redirecturi , state );
        //https://open.weixin.qq.com/connect/qrconnect?appid=wxed9954c01bb89b47&redirect_uri=http://localhost:8160&response_type=code&scope=snsapi_login&state=STATE#wechat_redirect
        return "redirect:"+url;
    }

    @Override
    public String wxLoginCallback(String code, String state, HttpSession session) {
        Object sessionState = session.getAttribute(Keys.WX_STATE_KEY);
        if(!StringUtils.isEmpty(state) && state.equals(sessionState)){
            System.out.println("code = " + code);
            System.out.println("state = " + state);
            //根据code获取wx用户的数据转为jwt
            String url = "https://api.weixin.qq.com/sns/oauth2/access_token" +
                    "?appid="+ wxLoginProperties.getAppid() +
                    "&secret="+ wxLoginProperties.getSecret() +
                    "&code="+code +
                    "&grant_type=authorization_code";
            //代码执行http请求访问url 获取accessToken
            HttpClientUtils client = new HttpClientUtils(url);
            try {
                client.get();//发起get请求
                String content = client.getContent();//获取请求体内容
                //content = {"access_token":"45_RuTFZUJA8AX8V6y5bj0lqkO14tSS0NKJyNbF2aNM713pViyXBLi7Fds1sb3rDvn7kWvVX32wbEX08DOPeXpCI6x075u_pjuy5zIi8RPV8Co","
                // expires_in":7200,"refresh_token":"45_udUGn_g5ozvh-FP_IPWtHpgIrnEnF079O0RcdD4OpQJ4vIA1Tq7dq6DQwnw7P73oHIms5NqiFYQ2HQbR9V5JUMwvTjhV-fULIJGq64fUjJ8",
                // "openid":"o3_SC52lXKutKEoVA7ucrh9zKBfQ",
                // "scope":"snsapi_login","unionid":"oWgGz1DWf5rtMIS88O6JN_aJR4NM"}
                System.out.println("content = " + content);
                Gson gson = new Gson();
                Map map = gson.fromJson(content, Map.class);
                //content = {"errcode":40163,"errmsg":"code been used, hints: [ req_id: 6GBCoCore-S_9Laa ]"}
                //判断是否成功，如果成功解析出at和openid继续获取用户信息
                if(map.get("errcode")!=null){
                    //获取失败，给用户失败的响应
                    return "redirect:http://localhost:3000/errorpage";  // 让浏览器显示错误原因
                }
                String accessToken = (String) map.get("access_token");
                String openid = (String) map.get("openid");
                //判断openid的用户之前是否登录过我们的系统，如果登录过从自己的数据库中查询该用户的数据
                //如果没登录 继续执行下面的代码从wx用户中心获取用户数据
                LambdaQueryWrapper<Member> queryWrapper = new LambdaQueryWrapper<>();
                queryWrapper.eq(Member::getOpenid , openid);
                Member member = memberMapper.selectOne(queryWrapper);
                if(member==null){
                    //wx用户第一次访问系统
                    //根据accessToken获取openid wx用户的wx信息
                    url = "https://api.weixin.qq.com/sns/userinfo" +
                            "?access_token="+ accessToken +
                            "&openid=" +openid;
                    client = new HttpClientUtils(url);
                    client.get();
                    content = client.getContent();
                    map = gson.fromJson(content, Map.class);
                    if(map.get("errorcode")!=null){
                        //获取用户信息失败
                        return "redirect:http://localhost:3000/errorpage";
                    }
                    String nickname = (String) map.get("nickname");
                    String sex = map.get("sex").toString();
                    String headimgurl = (String) map.get("headimgurl");
                    System.out.println("headimgurl = " + headimgurl);
                    System.out.println("sex = " + sex);
                    System.out.println("nickname = " + nickname);
                    //如果该用户是第一次使用wx登录，将该用户的数据存到数据库中变为我们自己的用户
                    member = new Member();
                    member.setOpenid(openid);
                    member.setNickname(nickname);
                    member.setSex((int) Double.parseDouble(sex));
                    member.setAvatar(headimgurl);
                    memberMapper.insert(member);
                    System.out.println("openid: "+ openid+" 第一次访问系统，保存用户数据成功");
                }
                //将用户信息封装为jwt交给前端项目，前端可以基于jwt获取用户信息显示到页面中
                JwtInfo jwtInfo = new JwtInfo();
                jwtInfo.setId(member.getId());
                jwtInfo.setAvatar(member.getAvatar());
                jwtInfo.setNickname(member.getNickname());
                String token = JwtHelper.createToken(jwtInfo);
                System.out.println("token = " + token);
                //让浏览器访问localhost:3000?jwt=xxx
                return "redirect:http://localhost:3000?token="+token;
            } catch (Exception e) {
                e.printStackTrace();
                return "redirect:http://localhost:3000/errorpage";
            }

        }
        return "redirect:http://localhost:3000/errorpage";// state 字符串的值比较错误
    }
}
